最近工作剛好使用到 gRPC,趁這個機會來了解一下他和 Restful API 的 diff。
在這個例子中,
因為 HTTP 的升級和較簡單的資料格式,有可能比 JSON 快到五倍之多。
是由 proto 所生成的代理程式碼,可以想像成是 interface,讓我們不用管底層的傳輸或資料序列化,可以直接來呼叫 gRPC 遠程的服務。
我們用 python 來建立一個範例
首先,先建立一個 example.proto
syntax = "proto3";
package example;
service ExampleService {
rpc Add (AddRequest) returns (AddResponse);
}
message AddRequest {
int32 a = 1; # 這是序列化 不是賦值
int32 b = 2; # 這是序列化 不是賦值
}
message AddResponse {
int32 result = 1; # 這是序列化 不是賦值
}
接著用 grpc_tools 產生兩個檔案
python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. example.proto
我們就可以利用這兩個檔案來寫出 server 和 client 端。
import grpc
from concurrent import futures
import example_pb2
import example_pb2_grpc
class ExampleServiceServicer(example_pb2_grpc.ExampleServiceServicer):
def Add(self, request, context):
# 實現 Add 服務
result = request.a + request.b
return example_pb2.AddResponse(result=result)
def serve():
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
example_pb2_grpc.add_ExampleServiceServicer_to_server(ExampleServiceServicer(), server)
server.add_insecure_port('[::]:50051')
print("gRPC server running on port 50051")
server.start()
server.wait_for_termination()
if __name__ == '__main__':
serve()
import grpc
import example_pb2
import example_pb2_grpc
def run():
# 連接 gRPC server
with grpc.insecure_channel('localhost:50051') as channel:
stub = example_pb2_grpc.ExampleServiceStub(channel)
# 發送 Add 請求
response = stub.Add(example_pb2.AddRequest(a=3, b=4))
print(f"Add result: {response.result}")
if __name__ == '__main__':
run()
我們先執行 server.py ,接著執行 client.py ,就可以看到我們的結果囉!
Add result: 7